/**
 * 
 */
package com.gr.staffpm.pages.projects;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.odlabs.wiquery.ui.datepicker.DatePicker;
import org.wicketstuff.annotation.mount.MountPath;
import org.wicketstuff.annotation.strategy.MountHybrid;

import com.gr.staffpm.StaffPMWebPage;
import com.gr.staffpm.datatypes.Group;
import com.gr.staffpm.datatypes.Project;
import com.gr.staffpm.datatypes.Role;
import com.gr.staffpm.datatypes.Task;
import com.gr.staffpm.datatypes.TaskImportance;
import com.gr.staffpm.datatypes.User;
import com.gr.staffpm.google.utils.GCalUtils;
import com.gr.staffpm.model.StringModel;
import com.gr.staffpm.pages.behaviour.FocusOnLoadBehavior;
import com.gr.staffpm.pages.error.UnauthorizedPage;
import com.gr.staffpm.projects.model.TaskPermission;
import com.gr.staffpm.security.constants.CRUDTaskPermission;
import com.gr.staffpm.security.constants.StaffPMRoles;
import com.gr.staffpm.security.service.UserService;
import com.gr.staffpm.tasks.model.TaskImportanceChoiceRenderer;
import com.gr.staffpm.tasks.model.UserChoiceRenderer;
import com.gr.staffpm.tasks.service.TaskService;
import com.gr.staffpm.widget.jqgrid.EditableGrid;
import com.gr.staffpm.widget.jqgrid.column.AbstractEditablePropertyColumn;
import com.gr.staffpm.widget.jqgrid.column.EditableCellPanel;
import com.gr.staffpm.widget.jqgrid.column.EditableDropDownCellPanel;


/**
 * @author Graham Rhodes 11 Apr 2011 00:38:50
 */
@MountHybrid
@MountPath(path = "secure/AddTask")
public class AddTaskPage extends StaffPMWebPage {

    @SpringBean(name = "taskService")
    private TaskService taskService;
    @SpringBean(name = "userService")
    private UserService userService;
    private Task newTask = new Task();
    private final Project project;
    private final TextField<String> summary = new TextField<String>("summary", new StringModel(""));
    private DropDownChoice<User> assignee = null;
    private DropDownChoice<TaskImportance> importance = null;
    private final TextArea<String> description = new TextArea<String>("description", new StringModel(""));
    private final DatePicker<Date> dueDate = new DatePicker<Date>("dueDate", Date.class);
    private final List<TaskPermission> permissions = new ArrayList<TaskPermission>();

    public AddTaskPage(final Project project) {
        this.project = project;
        boolean owner = userService.getCurrentUser().equals(project.getOwner());
        boolean admin = SecurityUtils.getSubject().hasRole(StaffPMRoles.ADMIN);

        if (SecurityUtils.getSubject().isPermitted("project:createtasks:" + project.getProjectId()) || admin || owner) {
            Form<Task> form = new Form<Task>("addTaskForm", new CompoundPropertyModel<Task>(newTask)) {

                private static final long serialVersionUID = 1L;

                @Override
                protected void onSubmit() {
                    AddTaskPage.this.onSubmit();
                }
            };
            add(form);

            add(new FeedbackPanel("feedback"));

            summary.setRequired(true);
            summary.setEscapeModelStrings(true);
            summary.add(new FocusOnLoadBehavior());
            form.add(summary);

            User currUser = userService.getCurrentUser();
            Set<Group> groups = currUser.getGroups();
            form.add(assignee =
                    new DropDownChoice<User>(
                            "assignee",
                            userService.getUsersInGroupByGroupName(groups.iterator().next().getName(), currUser, userService.getUsersHighestLevel(currUser)),
                            new UserChoiceRenderer()));
            assignee.setRequired(true);

            form.add(importance = new DropDownChoice<TaskImportance>("importance", taskService.getAllImportances(), new TaskImportanceChoiceRenderer()));
            importance.setRequired(true);

            dueDate.setRequired(true);
            dueDate.setEscapeModelStrings(true);
            form.add(dueDate);

            form.add(new EditableGrid<TaskPermission>("grid", getColumns(), new ArrayList<TaskPermission>(), new TaskPermission()) {

                private static final long serialVersionUID = 1L;

                @Override
                protected void onSave(TaskPermission pp, AjaxRequestTarget target) {
                    if (permissions.contains(pp)) {
                        permissions.remove(pp);
                    }
                    permissions.add(pp);
                }

                @Override
                protected void onDelete(TaskPermission pp, AjaxRequestTarget target) {
                    permissions.remove(pp);
                }

            });

            description.setEscapeModelStrings(true);
            form.add(description);

            Button cancel = new Button("cancelButton") {

                private static final long serialVersionUID = 1L;

                @Override
                public void onSubmit() {
                    setResponsePage(ViewProject.class, new PageParameters("id=" + project.getProjectId()));
                }

            };
            cancel.setDefaultFormProcessing(false);
            form.add(cancel);
        } else
            setResponsePage(UnauthorizedPage.class);
    }

    private List<AbstractEditablePropertyColumn<TaskPermission>> getColumns() {
        List<AbstractEditablePropertyColumn<TaskPermission>> columns = new ArrayList<AbstractEditablePropertyColumn<TaskPermission>>();
        columns.add(new AbstractEditablePropertyColumn<TaskPermission>(new Model<String>("Role"), "role") {

            private static final long serialVersionUID = 1L;

            @Override
            @SuppressWarnings({ "unchecked", "rawtypes" })
            public EditableCellPanel getEditableCellPanel(String componentId) {
                return new EditableDropDownCellPanel(componentId, this, userService.getAllRoles(), new ChoiceRenderer<Role>("role", "roleId"));
            }

        });
        columns.add(new AbstractEditablePropertyColumn<TaskPermission>(new Model<String>("Permission"), "permission") {

            private static final long serialVersionUID = 1L;

            @Override
            @SuppressWarnings({ "unchecked", "rawtypes" })
            public EditableCellPanel getEditableCellPanel(String componentId) {
                return new EditableDropDownCellPanel(componentId, this, CRUDTaskPermission.valuesAsList(), new ChoiceRenderer<CRUDTaskPermission>("name", "ordinal"));
            }

        });
        return columns;
    }

    protected void onSubmit() {
        User currUser = userService.getCurrentUser();

        newTask.setAssignee(assignee.getModelObject());
        newTask.setCreated(new Date());
        newTask.setCreatedBy(currUser);
        newTask.setDueDate(dueDate.getModelObject());
        newTask.setLastUpdated(new Date());
        newTask.setProject(project);
        newTask.setQueued(false);
        newTask.setResolved(false);
        newTask.setStatus(taskService.getOpenStatus());
        newTask.setSummary(summary.getValue());
        newTask.setUpdatedBy(currUser);
        newTask.setImportance(importance.getModelObject());
        newTask.setDescription(description.getValue());
        newTask.setName(project.getKey() + "_");

        newTask = taskService.createTask(newTask);

        newTask.setName(project.getKey() + "_" + newTask.getTaskId());
        taskService.updateTask(newTask);

        for (TaskPermission pp : permissions) {
            userService.createPermission(pp.getRole(), pp.getPermission(), newTask);
        }

        if (currUser.isGcalEnabled() && (currUser.getGcalAuth() != null)) {
            GCalUtils.addTaskToGCal(newTask, userService, newTask.getAssignee());
        }

        setResponsePage(ViewProject.class, new PageParameters("id=" + project.getProjectId()));
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.StaffPMWebPage#getTitle()
     */
    @Override
    public String getTitle() {
        return "Add Task - StaffPM";
    }

}
